#include"Task.hpp"
#include<vector>
#include<string>
#include<fcntl.h>
#include<unistd.h>
#include<assert.h>
#include<iostream>
#include<sys/types.h>
#include<stdlib.h>
#include<sys/wait.h>
#include<ctime>

const int processnum=10;
std::vector<task_t> tasks;

class channel{
public:
    channel(int cmdfd,int slaverid,std::string processname)
    :_cmdfd(cmdfd)
    ,_slaverid(slaverid)
    ,_processname(processname)
    {}

public:
    int _cmdfd;//发送任务的文件描述符
    pid_t _slaverid;//进程pid
    std::string _processname;//子进程名字
};

void slaver()
{
    while(true)
    {
        int n=-1;
        int re=read(0,&n,sizeof(int));

        if(n>=0&&n<tasks.size())
        {
            std::cout<<"My is "<<getpid()<<" My task is "<<n<<std::endl;
            tasks[n]();
        }
        if(re==0)
        {
            break;
        }
    }
}

void InitprocessPool(std::vector<channel> * channels)
{
    int count=0;
    while(count<processnum)
    {
        int pipefd[2];
        int re=pipe(pipefd);
        assert(!re);

        pid_t id=fork();

        if(id==0)
        {
            close(pipefd[1]);
            dup2(pipefd[0],0);
            close(pipefd[0]);
            slaver();
            std::cout<<getpid()<<": quit"<<std::endl;
            exit(0);
        }

        close(pipefd[0]);
        std::string name="process-"+std::to_string(count);
        channels->push_back(channel(pipefd[1],id,name));
        count++;
    }
}

void debug(const std::vector<channel> & channels)
{
    for(auto &e :channels)
    {
        std::cout<<e._cmdfd<<" "<<e._slaverid<<" "<<e._processname<<std::endl;
    }
}

void menu()
{
    std::cout<<"****************************************"<<std::endl;
    std::cout<<"***1.更新日志            2.更新技能冷却***"<<std::endl;
    std::cout<<"***3.更新野怪和经验       4.检测更新   ***"<<std::endl;
    std::cout<<"***              0.退出              ***"<<std::endl;
    std::cout<<"****************************************"<<std::endl;

}

void ctrlSlaver(const std::vector<channel>& channels)
{
    while(true)
    {
        //选择任务
        menu();
        int sel;
        std::cin>>sel;

        if(sel==0)
        {
            std::cout<<"quit suceess"<<std::endl;
            break;
        }
        else if(sel<0||sel>4)
        {
            std::cout<<"sel error"<<std::endl;
            break;
        }

        int cmdcode=sel-1;

        //选择进程
        int pnum=rand()%channels.size();

        std::cout<<"I am father,"<<"sel task is "<<sel<<",sel processnum is "<<channels[pnum]._slaverid<<std::endl;
        write(channels[pnum]._cmdfd, &cmdcode, sizeof(cmdcode));
    }

}

void Quitprocess(const std::vector<channel>& channels)
{
    for(auto& e:channels)
    {
        close(e._cmdfd);
    }

    for(auto& e:channels)
    {
        waitpid(e._slaverid,nullptr,0);
    }
}

int main()
{
    Loadtask(&tasks);
    srand(time(nullptr)^getpid()^1023);
    //组织
    std::vector<channel> channels;
    //初始化
    InitprocessPool(&channels);
    debug(channels);
    //调度子进程
    ctrlSlaver(channels);

    //处理
    Quitprocess(channels);

    return 0;
}